package com.ict.ms.artificial.service.api.impl;


import org.springframework.stereotype.Service;

import com.ict.ms.artificial.facade.api.IArtificialService;
import com.ict.ms.artificial.facade.model.AppointTarget;
import com.ict.ms.artificial.facade.model.Attribute;
import com.ict.ms.artificial.facade.model.Config_Fusion;
import com.ict.ms.artificial.facade.model.FuseTargetFromSource;
import com.ict.ms.artificial.facade.model.Manual_Association;
import com.ict.ms.artificial.facade.model.UpdateTarget;
import com.ict.ms.artificial.service.dao.IArtificialDao;
import com.ict.ms.artificial.service.dao.IAttributeDao;
import com.ict.ms.artificial.service.rabbitmq.MQTopicPublish_Artificial;
import com.ict.ms.artificial.service.rabbitmq.ProperUtils_Artificial;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service("artificialService")
public class ArtificialService implements  IArtificialService{
    @Resource
    IArtificialDao iArtificialDao;

    @Resource
    IAttributeDao attributeDao;

    /**
     * 目标合批
     *
     * @param shipId1 合批目标1
     * @param shipId2 合批目标2
     * @return
     */
    public AppointTarget mergeTarget(int shipId1, int shipId2) {
        try {
            team.iOceanPlus.PB.Command.PBCommand.Builder pbCommand = team.iOceanPlus.PB.Command.PBCommand.newBuilder();

            team.iOceanPlus.PB.Command.PBCommandAssociation.Builder pbCommandAssociation = team.iOceanPlus.PB.Command.PBCommandAssociation.newBuilder();
            pbCommandAssociation.addListTargetID(shipId1);
            pbCommandAssociation.addListTargetID(shipId2);

            pbCommand.addListCommandAssoc(pbCommandAssociation);//PB设置

            ProperUtils_Artificial properUtils = new ProperUtils_Artificial();
            MQTopicPublish_Artificial mqTopicPublish = new MQTopicPublish_Artificial(properUtils.getHost(), properUtils.getUser(), properUtils.getPassWord(),
                    properUtils.getExchange());

            if (mqTopicPublish.BaseConnection(properUtils.getPort()) != 0) {
                System.out.println("连接RabbiqMQ失败");
                return null;
            }

            //PB打包成byte[]
            team.iOceanPlus.PB.Command.PBCommand bui = pbCommand.build();
            byte[] result = bui.toByteArray();

            /**
             * operation_Type
             * 1：合批
             * 2：分离
             * 3：属性修改
             */
            //获取系统当前时间戳
            int int_pro_time = (int) (System.currentTimeMillis() / 1000);
            Manual_Association manual_association = new Manual_Association(1, result, int_pro_time);

            try {
                iArtificialDao.saveArtificial(manual_association);

                //调用RabbitMQ发布到指定的队列
                if (!mqTopicPublish.Publish(properUtils.getRoutingKey(), result)) {
                    System.out.println("发送RabbitMQ消息失败");
                    return null;
                }

                AppointTarget appointTarget = iArtificialDao.getFuseTargetBy2ShipIdTimeDesc(shipId1, shipId2);
                return appointTarget;
            } catch (Exception e) {
                System.out.println("人工干预记录存储失败：" + e);
                return null;
            }
        } catch (Exception e) {
            System.out.println("操作失败" + e);
            return null;
        }
    }

    /**
     * 目标分批
     *
     * @param shipId 分批的目标号
     * @return
     */
    public List<FuseTargetFromSource> separateTarget(int shipId) {
        try {
            team.iOceanPlus.PB.Command.PBCommand.Builder pbCommand = team.iOceanPlus.PB.Command.PBCommand.newBuilder();

            team.iOceanPlus.PB.Command.PBCommandDeAssociation.Builder pbCommandDeAssociation = team.iOceanPlus.PB.Command.PBCommandDeAssociation.newBuilder();
            pbCommandDeAssociation.setTargetID(shipId);
            pbCommand.addListCommandDeAssoc(pbCommandDeAssociation);//PB设置

            ProperUtils_Artificial properUtils = new ProperUtils_Artificial();
            MQTopicPublish_Artificial mqTopicPublish = new MQTopicPublish_Artificial(properUtils.getHost(), properUtils.getUser(), properUtils.getPassWord(),
                    properUtils.getExchange());

            if (mqTopicPublish.BaseConnection(properUtils.getPort()) != 0) {
                System.out.println("连接RabbiqMQ失败");
                return null;
            }

            //PB打包成byte[]
            team.iOceanPlus.PB.Command.PBCommand bui = pbCommand.build();
            byte[] result = bui.toByteArray();

            /**
             * operation_Type
             * 1：合批
             * 2：分离
             * 3：属性修改
             */
            //获取系统当前时间戳
            int int_pro_time = (int) (System.currentTimeMillis() / 1000);
            Manual_Association manual_association = new Manual_Association(2, result, int_pro_time);
            try {
                iArtificialDao.saveArtificial(manual_association);

                //调用RabbitMQ发布到指定的队列
                if (!mqTopicPublish.Publish(properUtils.getRoutingKey(), result)) {
                    System.out.println("发送RabbitMQ消息失败");
                    return null;
                }

                List<FuseTargetFromSource> fuseTargetFromSourceList = iArtificialDao.getListTargetByArtificial(shipId);
                return fuseTargetFromSourceList;
            } catch (Exception e) {
                System.out.println("人工干预记录存储失败：" + e);
                return null;
            }
        } catch (Exception e) {
            System.out.println("操作失败" + e);
            return null;
        }
    }

    /**
     * 目标属性修改
     *
     * @param updateTarget
     * @return
     */
    public AppointTarget updateTarget(UpdateTarget updateTarget) {
        try {
            //存储属性修改
            if(!updateAttributeSaveTable(updateTarget)){
                System.out.println("属性存储失败！");
                return null;
            }

            team.iOceanPlus.PB.Command.PBCommand.Builder pbCommand = team.iOceanPlus.PB.Command.PBCommand.newBuilder();

            team.iOceanPlus.PB.Command.PBCommandUpdateTargetProperty.Builder pbCommandUpdateTargetProperty = team.iOceanPlus.PB.Command.PBCommandUpdateTargetProperty.newBuilder();
            pbCommandUpdateTargetProperty.setTargetID(updateTarget.getTargetID());

            switch (updateTarget.getTargetType()) {
                case 1:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_CargoShip);
                    break;
                case 2:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_SARShip);
                    break;
                case 3:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_Tanker);
                    break;
                case 4:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_Tug);
                    break;
                case 5:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_FishingShip);
                    break;
                case 6:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_TowingShip);
                    break;
                case 7:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_PassengerShip);
                    break;
                case 100:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_Others);
                    break;
                //fcc修改部分
                case 8:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_MilitaryShip);
                    break;
                case 9:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_LawEnforcementShip);
                    break;
                case 10:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_WIGShip);
                    break;
                case 11:
                    pbCommandUpdateTargetProperty.setEnumTargetType(team.iOceanPlus.PB.CommonEnum.PB_Enum_Aggregated_AIS_Ship_Type.EV_AggregatedAISShipType_HSCShip);
                    break;
                //fcc修改部分
                default:
                    return null;
            }

            pbCommandUpdateTargetProperty.setShipName(updateTarget.getTargetName());
            pbCommandUpdateTargetProperty.setCountryName(updateTarget.getCountry());

            pbCommand.addListCommandUpdateTargetProperty(pbCommandUpdateTargetProperty);//PB设置

            ProperUtils_Artificial properUtils = new ProperUtils_Artificial();
            MQTopicPublish_Artificial mqTopicPublish = new MQTopicPublish_Artificial(properUtils.getHost(), properUtils.getUser(), properUtils.getPassWord(),
                    properUtils.getExchange());

            if (mqTopicPublish.BaseConnection(properUtils.getPort()) != 0) {
                System.out.println("连接RabbiqMQ失败");
                return null;
            }

            //PB打包成byte[]
            team.iOceanPlus.PB.Command.PBCommand bui = pbCommand.build();
            byte[] result = bui.toByteArray();

            /**
             * operation_Type
             * 1：合批
             * 2：分离
             * 3：属性修改
             */
            //获取系统当前时间戳
            int int_pro_time = (int) (System.currentTimeMillis() / 1000);
            Manual_Association manual_association = new Manual_Association(3, result, int_pro_time);
            try {
                iArtificialDao.saveArtificial(manual_association);

                //调用RabbitMQ发布到指定的队列
                if (!mqTopicPublish.Publish(properUtils.getRoutingKey(), result)) {
                    System.out.println("发送RabbitMQ消息失败");
                    return null;
                }

                AppointTarget appointTarget = iArtificialDao.getFuseTargetByShipIdTimeDesc(updateTarget.getTargetID());

                //返回修改的目标属性
                appointTarget.setShip_type(updateTarget.getTargetType());
                appointTarget.setShip_name(updateTarget.getTargetName());
                appointTarget.setCountry_name(updateTarget.getCountry());
                //返回修改的目标属性

                return appointTarget;
            } catch (Exception e) {
                System.out.println("人工干预记录存储失败：" + e);
                return null;
            }
        } catch (Exception e) {
            System.out.println("操作失败" + e);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据信息类型消批设置发MQ
     * @param timeSet
     * @param typeSet
     * @param userName
     * @return
     */
    public boolean setMQBatchEliminationForType(String[] timeSet,String[] typeSet,String userName){
        try {
            team.iOceanPlus.PB.Config.PBConfig.Builder pbConfig = team.iOceanPlus.PB.Config.PBConfig.newBuilder();
            if(timeSet.length!=typeSet.length){
                return false;
            }else{
                for(int i=0;i<timeSet.length;i++){
                    team.iOceanPlus.PB.Config.PBConfigFusion.Builder pbConfigFusion = team.iOceanPlus.PB.Config.PBConfigFusion.newBuilder();
                    //此处使用目标编号类型传输信息类型值（胡、吴确认这么使用）
                    switch (Integer.parseInt(typeSet[i])){
                        case 1:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_MMSI);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 2:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_IMO);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 3:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_BeidouID);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 4:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_HaijianID);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 5:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_ArgosAndMarineSatID);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 15:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_Fusion);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        case 16:
                            pbConfigFusion.setTargetIDType(team.iOceanPlus.PB.CommonEnum.PB_Enum_TargetID_Type.EV_TargetIDType_Others);
                            pbConfigFusion.setSecondsBeforeDeleteTarget(Integer.parseInt(timeSet[i]));
                            pbConfig.addListConfigFusion(pbConfigFusion);
                            break;
                        default:
                            break;
                    }
                }
                }

            ProperUtils_Artificial properUtils = new ProperUtils_Artificial();
            MQTopicPublish_Artificial mqTopicPublish = new MQTopicPublish_Artificial(properUtils.getHost(), properUtils.getUser(), properUtils.getPassWord(),
                    properUtils.getExchange());

            if (mqTopicPublish.BaseConnection(properUtils.getPort()) != 0) {
                System.out.println("连接RabbiqMQ失败");
                return false;
            }

            //PB打包成byte[]
            team.iOceanPlus.PB.Config.PBConfig bui = pbConfig.build();
            byte[] result = bui.toByteArray();

            //调用RabbitMQ发布到指定的队列
            if (!mqTopicPublish.Publish(properUtils.getRoutingKey(), result)) {
                System.out.println("发送RabbitMQ消息失败");
                return false;
            }
            return true;
        } catch (Exception e) {
            System.out.println("操作失败" + e);
            return false;
        }
    }

    /**
     * 根据信息类型消批设置存库
     * @param timeSet
     * @param typeSet
     * @param userName
     * @return
     */
    public boolean setBatchEliminationForType(String[] timeSet,String[] typeSet,String userName) {
        if(timeSet.length!=typeSet.length){
            return false;
        }else{
            List<Config_Fusion> config_fusionList=new ArrayList<Config_Fusion>();
            Config_Fusion config_fusion;
            for(int i=0;i<timeSet.length;i++){
                switch (Integer.parseInt(typeSet[i])){
                    case 1:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 2:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 3:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 4:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 5:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 15:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    case 16:
                        config_fusion=new Config_Fusion(Integer.parseInt(timeSet[i]),Integer.parseInt(typeSet[i]),userName);
                        config_fusionList.add(config_fusion);
                        break;
                    default:
                        break;
                }

            }
            try{
                iArtificialDao.setBatchEliminationList(config_fusionList);
                return true;
            }catch (Exception e){
                System.out.println("数据库操作失败："+e);
                return false;
            }
        }
    }


    /**
     * 消批获取
     *
     * @return
     */
    public Config_Fusion getBatchElimination() {
        try {
            Config_Fusion config_fusion = iArtificialDao.getBatchElimination();
            return config_fusion;
        } catch (Exception e) {
            System.out.println("数据操作失败" + e);
            return null;
        }
    }

    /**
     * 不同信息类型消批设置的获取
     * @return
     */
    public List<Config_Fusion> getBatchEliminationList() {
        try {
            List<Config_Fusion> config_fusionList = iArtificialDao.getBatchEliminationList();
            return config_fusionList;
        } catch (Exception e) {
            System.out.println("数据操作失败" + e);
            return null;
        }
    }

    /**
     * 属性修改时，负责存储之前属性与新的属性
     * @param newOne 修改后的属性
     * @return 是否成功存储
     */
    public boolean updateAttributeSaveTable(UpdateTarget newOne){
        //获得原有的属性，进行存储
        AppointTarget target=iArtificialDao.getFuseTargetByShipIdTimeDesc(newOne.getTargetID());
        UpdateTarget oldOne=new UpdateTarget(target.getTarget_id(),target.getShip_type(),target.getShip_name(),target.getCountry_name());
        try {
            Attribute attribute=new Attribute(newOne.getTargetID(),oldOne.getTargetType(),oldOne.getTargetName(),oldOne.getCountry(),newOne.getTargetType(),newOne.getTargetName(),newOne.getCountry());
            attributeDao.setAttribute(attribute);
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
